package cn.iocoder.yudao.module.trade.aftersale.dal.mysql;

import cn.iocoder.yudao.framework.business.basic.dao.mapper.CoreMapper;
import cn.iocoder.yudao.framework.business.basic.dao.query.CoreLambdaQueryWrapper;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.trade.aftersale.dal.dataobject.AfterSaleDO;
import cn.iocoder.yudao.module.trade.aftersale.vo.AfterSalePageReqVO;
import cn.iocoder.yudao.module.trade.aftersale.vo.AppAfterSalePageReqVO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

import java.util.Collection;
import java.util.List;

@Mapper
public interface AfterSaleMapper extends CoreMapper<AfterSaleDO> {

    default PageResult<AfterSaleDO> selectPage(AfterSalePageReqVO reqVO) {
        return selectPage(reqVO, new CoreLambdaQueryWrapper<AfterSaleDO>()
                .eqIfPresent(AfterSaleDO::getUserId, reqVO.getUserId())
                .likeIfPresent(AfterSaleDO::getNo, reqVO.getNo())
                .eqIfPresent(AfterSaleDO::getStatus, reqVO.getStatus())
                .eqIfPresent(AfterSaleDO::getType, reqVO.getType())
                .eqIfPresent(AfterSaleDO::getWay, reqVO.getWay())
                .likeIfPresent(AfterSaleDO::getOrderNo, reqVO.getOrderNo())
                .likeIfPresent(AfterSaleDO::getSpuName, reqVO.getSpuName())
                .betweenIfPresent(AfterSaleDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(AfterSaleDO::getId));
    }

    default PageResult<AfterSaleDO> selectPage(Long userId, AppAfterSalePageReqVO pageParam) {
        return selectPage(pageParam, new CoreLambdaQueryWrapper<AfterSaleDO>()
                .eqIfPresent(AfterSaleDO::getUserId, userId)
                .eqIfPresent(AfterSaleDO::getStatus, pageParam.getStatus())
                .orderByDesc(AfterSaleDO::getId));
    }

    default PageResult<AfterSaleDO> selectPageShopId(Long shopId, AppAfterSalePageReqVO pageParam) {
        return selectPage(pageParam, new CoreLambdaQueryWrapper<AfterSaleDO>()
                .eqIfPresent(AfterSaleDO::getShopId, shopId)
                .eqIfPresent(AfterSaleDO::getStatus, pageParam.getStatus())
                .orderByDesc(AfterSaleDO::getId));
    }

    default int updateByIdAndStatus(Long id, Integer status, AfterSaleDO update) {
        return update(update, new LambdaUpdateWrapper<AfterSaleDO>()
                .eq(AfterSaleDO::getId, id).eq(AfterSaleDO::getStatus, status));
    }

    default AfterSaleDO selectByIdAndUserId(Long id, Long userId) {
        return selectOne(AfterSaleDO::getId, id,
                AfterSaleDO::getUserId, userId);
    }

    default List<AfterSaleDO> selectByOrderIdAndUserId(Long orderId, Long userId) {
        return selectList(AfterSaleDO::getOrderId, orderId,
                AfterSaleDO::getUserId, userId);
    }

    default AfterSaleDO selectByIdAndShopId(Long id, Long shopId) {
        return selectOne(AfterSaleDO::getId, id,
                AfterSaleDO::getShopId, shopId);
    }

    default List<AfterSaleDO> selectByOrderId(Long orderId) {
        return selectList(AfterSaleDO::getOrderId, orderId);
    }

    default List<AfterSaleDO> selectByOrderIdAndShopId(Long orderId, Long shopId) {
        return selectList(AfterSaleDO::getOrderId, orderId,
                AfterSaleDO::getShopId, shopId);
    }

    default AfterSaleDO selectByNo(String no) {
        return selectOne(AfterSaleDO::getNo, no);
    }

    /**
     * 按单个产品计数
     */
    default Long selectCountByUserIdAndStatus(Long userId, Collection<Integer> statuses) {
        return selectCount(new CoreLambdaQueryWrapper<AfterSaleDO>()
                .eq(AfterSaleDO::getUserId, userId)
                .in(AfterSaleDO::getStatus, statuses));
    }

    /**
     * 按整单计数
     */
    @Select("""
            <script>
            SELECT COUNT(DISTINCT `order_id`) AS count
            FROM `trade_after_sale`
            WHERE deleted = FALSE AND user_id = #{userId} AND status IN
            <foreach item="id" collection="statuses" open="(" separator="," close=")">
                #{id}
            </foreach>
            </script>
            """)
    Long selectCountForUserDistinctByOrderId(@Param("userId") Long userId, @Param("statuses") Collection<Integer> statuses);

    /**
     * 按单个产品计数
     */
    default Long selectCountByShopIdIdAndStatus(Long shopId, Collection<Integer> statuses) {
        return selectCount(new CoreLambdaQueryWrapper<AfterSaleDO>()
                .eq(AfterSaleDO::getShopId, shopId)
                .in(AfterSaleDO::getStatus, statuses));
    }

    /**
     * 按整单计数
     */
    @Select("""
            <script>
            SELECT COUNT(DISTINCT `order_id`) AS count
            FROM `trade_after_sale`
            WHERE deleted = FALSE AND shop_id = #{shopId} AND status IN
            <foreach item="id" collection="statuses" open="(" separator="," close=")">
                #{id}
            </foreach>
            </script>
            """)
    Long selectCountForShopDistinctByOrderId(@Param("shopId") Long shopId, @Param("statuses") Collection<Integer> statuses);

    default AfterSaleDO searchBySupplyRelatedNo(String serviceSn) {
        CoreLambdaQueryWrapper<AfterSaleDO> wrapper = new CoreLambdaQueryWrapper<>();
        wrapper.eq(AfterSaleDO::getSupplyRelatedNo, serviceSn);
        wrapper.limitN(1);
        return selectOne(wrapper);
    }

    @Select("""
            SELECT DISTINCT `order_id`
            FROM `trade_after_sale`
            WHERE deleted = FALSE AND user_id = #{userId}
            """)
    List<Long> selectOrderIdsByUserId(@Param("userId") Long userId);

    @Select("""
            SELECT DISTINCT `order_id`
            FROM `trade_after_sale`
            WHERE deleted = FALSE AND user_id = #{userId} AND status = #{status}
            """)
    List<Long> selectOrderIdsByUserIdAndStatus(@Param("userId") Long userId, @Param("status") Integer status);

    @Select("""
            SELECT DISTINCT `order_id`
            FROM `trade_after_sale`
            WHERE deleted = FALSE AND shop_id = #{shopId}
            """)
    List<Long> selectOrderIdsByShopId(@Param("shopId") Long shopId);

    @Select("""
            SELECT DISTINCT `order_id`
            FROM `trade_after_sale`
            WHERE deleted = FALSE AND shop_id = #{shopId} AND status = #{status}
            """)
    List<Long> selectOrderIdsByShopIdAndStatus(@Param("shopId") Long shopId, @Param("status") Integer status);

}
